package com.wisdytech.common.shiro;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.wisdytech.linkdcs.system.dao.ISysResourceDao;
import com.wisdytech.linkdcs.system.dao.ISysRoleResourceDao;
import com.wisdytech.linkdcs.system.dao.ISysUserRoleDao;
import com.wisdytech.linkdcs.system.model.SysResource;
import com.wisdytech.linkdcs.system.model.SysRoleResource;
import com.wisdytech.linkdcs.system.model.SysUser;
import com.wisdytech.linkdcs.system.model.SysUserRole;
import com.wisdytech.linkdcs.system.service.IUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.mgt.SessionsSecurityManager;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Component
public class MyShiroRealm extends AuthorizingRealm {
	
	private Logger logger =LoggerFactory.getLogger(MyShiroRealm.class);
	
	@Resource
	private IUserService userService;
	@Resource
	private ISysUserRoleDao iSysUserRoleDao;
	@Resource
	private ISysRoleResourceDao iSysRoleResourceDao;
	@Resource
	private ISysResourceDao iSysResourceDao;
	//授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
		SimpleAuthorizationInfo authorizationInfo =new SimpleAuthorizationInfo();
		//角色字段
		Set<String> roles=new HashSet<>();
		roles.add("admin");
		authorizationInfo.setRoles(roles);
		
		//权限字段
		SysUser user = (SysUser) arg0.fromRealm(this.getClass().getName()).iterator().next();
		logger.info(">>>>>>>>>>>>>>>>权限检测<<<<<<<<<<<<<<<<<<< ");
		Set<String> stringPermissions=new HashSet<>();
		SysUserRole sysUserRole = new SysUserRole();
		sysUserRole.setUserId(user.getPkId());
		//查询用户与角色关联表
		SysUserRole sr = iSysUserRoleDao.selectOne(sysUserRole);
		//查询角色与资源关联表
		EntityWrapper<SysRoleResource> ew = new EntityWrapper<>();
		//TODO 关联查询而不是查很多次
		ew.eq("ROLE_ID", sr.getRoleId());
		List<SysRoleResource> srrlist = iSysRoleResourceDao.selectList(ew);
		for(SysRoleResource sysRoleResource : srrlist) {
			SysResource sysResource =iSysResourceDao.selectById(sysRoleResource.getResId());
			if(sysResource!=null) {
				if(sysResource.getPermission() !=null) {
					stringPermissions.add(sysResource.getPermission());
				}
			}

		}
		stringPermissions.add("test");
		authorizationInfo.setStringPermissions(stringPermissions);
		
		return authorizationInfo;
	}

	//认证 登陆
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		logger.info(">>>>>>>>>>>>>>>>登陆认证<<<<<<<<<<<<<<<<<<< ");
		UsernamePasswordToken tokens = (UsernamePasswordToken) token;
		String userName=tokens.getUsername();
		String password =String.valueOf(tokens.getPassword());
		
		SysUser sysUser =userService.getSystemUserByName(userName);
		//查询用户所属角色
		
		
		if(null == sysUser) {
			throw new UnknownAccountException();//用户不存在
		}
		
		String md5Password=new Md5Hash(password).toString().toUpperCase();
		
		if(!sysUser.getPassword().equals(md5Password)) {
			throw new IncorrectCredentialsException();//密码错误
		}
		
		
		//处理session
		SessionsSecurityManager securityManager = (SessionsSecurityManager) SecurityUtils.getSecurityManager();
        DefaultSessionManager sessionManager = (DefaultSessionManager) securityManager.getSessionManager();
        Collection<Session> sessions=
        		sessionManager.getSessionDAO().getActiveSessions();//获取已登录的用户session列表
        for(Session session : sessions) {
        	
        	//当前session 跳出
        	if(SecurityUtils.getSubject().getSession().getId().equals(session.getId())) {
        		break;
        	}
        	
        	//清楚该用户以前登录保存的session
        	SysUser sessioUser= (SysUser)session.getAttribute("user");
        	if(null != sessioUser) {
        		if(userName.equals(sessioUser.getUsername())){
        			logger.error("用户"+userName+" 重复登录，剔除中！！！！");
        			sessionManager.getSessionDAO().delete(session);
        		}
        	}
        	
        	
        }
        
		SimpleAuthenticationInfo authorizationInfo = new SimpleAuthenticationInfo(
				sysUser,password,this.getClass().getName());
		return authorizationInfo;
	}

}
